﻿// ==============================================================================
// Copyright (c) 2012 Bndy.Net, All rights reserved.
// Created by Bndy on 4/4/2012 8:31:12 PM
//
//                    * * * * * * * * * * * * * 
//                    * MAIL- bndy5337@163.com *       http://www.bndy.net
//                    * Q Q - 81795705 =========================================>
//                    * MSN - bndy5337@msn.com *
//                    * * * * * * * * * * * * * 
//
// ------------------------------------------------------------------------------
// 
// ==============================================================================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace Net.Bndy.Framework.SqlBuilders
{
    internal class MsSqlBuilder : SqlBuilder
    {
        public override string Insert(EntityBase entity)
        {
            string sqlFormat = "INSERT INTO [{0}]({1}) VALUES({2})";

            List<string> fields = new List<string>();
            List<string> values = new List<string>();

            foreach (KeyValuePair<string, object> kv in entity.GetAllPropertyValuePair())
            {
                fields.Add(kv.Key);
                values.Add(kv.Value == null ? string.Empty : kv.Value.ToString());
            }

            return string.Format(sqlFormat,
                entity.GetType().Name,
                string.Join(",", fields.ToArray()),
                string.Join(",", values.ToArray())
                );
        }

        public override string Update(EntityBase entity)
        {
            KeyValuePair<string, object>? primaryKey = entity.GetPrimaryKey();

            if (primaryKey.HasValue)
            {
                string sqlFormat = "UPDATE [{0}] SET {1} WHERE {2}";

                List<string> fv = new List<string>();
                Dictionary<string, object> pv = entity.GetAllPropertyValuePair();

                pv.Remove(primaryKey.Value.Key);

                foreach (KeyValuePair<string, object> kv in pv)
                {
                    fv.Add(string.Format("{0}={1}", kv.Key, kv.Value));
                }

                return string.Format(sqlFormat,
                    entity.GetType().Name,
                    string.Join(",", fv.ToArray()),
                    string.Format("{0}={1}", primaryKey.Value.Key, primaryKey.Value.Value)
                    );
            }
            else
            {
                throw new Exception(ExMsg_RequiredPrimaryKey);
            }
        }

        public override string Delete(EntityBase entity)
        {
            KeyValuePair<string, object>? primaryKey = entity.GetPrimaryKey();

            if (primaryKey.HasValue)
            {
                string sqlFormat = "DELETE FROM [{0}] WHERE {1}";

                return string.Format(sqlFormat, entity.GetType().Name,
                    string.Format("{0}={1}", primaryKey.Value.Key, primaryKey.Value.Value)
                    );
            }
            else
            {
                throw new Exception(ExMsg_RequiredPrimaryKey);
            }
        }

        private static string GetSqlString(object value)
        {
            string result = "''";

            if (value != null)
            {
                switch (Type.GetTypeCode(value.GetType()))
                {
                    case TypeCode.Byte:
                    case TypeCode.Decimal:
                    case TypeCode.Double:
                    case TypeCode.Int16:
                    case TypeCode.Int32:
                    case TypeCode.Int64:
                    case TypeCode.SByte:
                    case TypeCode.Single:
                    case TypeCode.UInt16:
                    case TypeCode.UInt32:
                    case TypeCode.UInt64:
                        result = value.ToString();
                        break;

                    case TypeCode.Char:
                    case TypeCode.DateTime:
                    case TypeCode.Empty:
                    case TypeCode.String:
                        result = string.Format("'{0}'", value);
                        break;

                    case TypeCode.Boolean:
                        result = true.Equals(value) ? "1" : "0";
                        break;

                    case TypeCode.DBNull:
                        result = "NULL";
                        break;
                }
            }

            return result;
        }
    }
}
